package dp;

import java.util.Arrays;

/**
 * 213. 打家劫舍 II
 * 你是一个专业的小偷，计划偷窃沿街的房屋，每间房内都藏有一定的现金。这个地方所有的房屋都 围成一圈 ，
 * 这意味着第一个房屋和最后一个房屋是紧挨着的。同时，相邻的房屋装有相互连通的防盗系统，
 * 如果两间相邻的房屋在同一晚上被小偷闯入，系统会自动报警 。
 * 给定一个代表每个房屋存放金额的非负整数数组，计算你 在不触动警报装置的情况下 ，今晚能够偷窃到的最高金额。
 *
 */
public class HouseRober_213 {
    // 不一定是二维dp数组，应该先从一维考虑起
    public int rob(int[] nums) {
        // dp[i]表示偷到了i号房子的最大金额
        if (nums.length == 1) {
            return nums[0];
        } else if (nums.length == 2) {
            return Math.max(nums[0], nums[1]);
        }

        // 分2种情况，假如偷了1号房，则不能偷最后的房子
        int[] dp = new int[nums.length];
        // base case
        dp[0] = nums[0];
        dp[1] = nums[0];
        for (int i = 2; i < nums.length - 1; i++) {
            // 在i号房子的最大金额，子问题：
            // 1. 昨天没偷，最大金额是前天的最大金额，今天偷 2. 昨天偷了，今天就不偷
            dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        int maxA = dp[dp.length - 2];

        Arrays.fill(dp, 0);
        // 假如没偷1号房，则可以偷最后的房子
        dp[0] = 0;
        dp[1] = nums[1];
        dp[2] = Math.max(nums[1], nums[2]);
        for (int i = 3; i < nums.length; i++) {
            // 在i号房子的最大金额，子问题：
            // 1. 昨天没偷，最大金额是前天的最大金额，今天偷 2. 昨天偷了，今天就不偷
            dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
        }

        int maxB = dp[dp.length - 1];
        return Math.max(maxA, maxB);
    }
}
